#pragma once

#pragma unmanaged

#include <BWSAL/Task.h>

#pragma managed

#include "..\BWAPI\IIdentifiedObject.h"

#include "Build.h"
#include "TaskState.h"
#include "BuildEvent.h"
#include "Interfaces\IMetaUnit.h"

namespace BroodWar
{
	namespace Addon
	{
		ref class MetaUnitVariable;
		
		public ref class Task : public Api::IIdentifiedObject
		{
		internal:
			bool dispose;
			BWSAL::Task* instance;

			Task(BWSAL::Task* task);
			Task(BWSAL::Task task);
			~Task();
			!Task();
		public:
			Task();
			Task(BuildType type);

			virtual property int Id { int get(); }
			
			property Build^ BuildType { Build^ get(); }
			property MetaUnitVariable^ Builder { MetaUnitVariable^ get(); }
			property MetaUnitVariable^ SecondBuilder { MetaUnitVariable^ get(); }
			property BuildUnit^ CreatedUnit { BuildUnit^ get(); }
			property BuildUnit^ SecondCreatedUnit { BuildUnit^ get(); }
			property TilePosition^ BuildLocation { TilePosition^ get(); }
			property TilePosition^ SeedLocation { TilePosition^ get(); }
			BuildEvent^ GetReserveBuilderEvent();
			BuildEvent^ GetReserveResourcesEvent();
			BuildEvent^ GetReleaseBuilderEvent();
			BuildEvent^ GetCompleteBuildTypeEvent();
			// returns true if this task has been scheduled on this frame
			property bool IsScheduledThisFrame { bool get(); }
			// returns true if the start time has occurred, but the completion time has not
			property bool IsWaiting { bool get(); }
			property bool IsRunning { bool get(); }
			property bool IsCompleted { bool get(); }
			property TaskState^ State { TaskState^ get(); void set(TaskState^ state); }
			property int EarliestStartTime { int get(); void set(int time); }
			property int RunTime { int get(); void set(int time); }
			property int ExecuteTime { int get(); void set(int time); }
			property int CompletionTime { int get(); void set(int time); }
			property int LastOrderTime { int get(); }
			void SetLastOrderTime();
			property bool IsRelocatable { bool get(); void set(bool value); }
			// sets scheduled to true for the current frame
			void SetScheduledThisFrame();
			void SetBuildLocation(TilePosition^ buildLocation);
			void SetSeedLocation(TilePosition^ seedLocation);
			void AssignBuilder(IMetaUnit^ builder);
			void AssignBuilders(IMetaUnit^ builder, IMetaUnit^ secondBuilder);
			void AssignBuilders(IEnumerable<IMetaUnit^>^ builders);
			void UseAnyBuilder();
			property bool CanUseAnyBuilder { bool get(); }
			
			virtual String^ ToString() override;
		};

		Task^ ConvertTask(BWSAL::Task* task);
		BWSAL::Task* ConvertTask(Task^ task);
	}
}